package org.ksystem.common.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.ksystem.common.enums.DateEnum;

/**
 * 日期工具类。
 */
public class DateUtil {

    public static final String PATTERN_DATE = "yyyy-MM-dd";

    /**
     * 格式化日期
     * 
     * @param date
     *            要格式化的日期
     * @param fs
     *            日期格式，使用常量
     * @return 格式化后的日期
     */
    public static String formatDate(Date date, DateEnum fs) {
        if (date == null) {
            return "";
        }
        if (fs == null) {
            // 默认YYYY-MM-DD格式
            fs = DateEnum.YYYYMMDD_BYSEP;
        }
        // 设定格式
        SimpleDateFormat sdf = new SimpleDateFormat(fs.getValue());
        // 返回最终格式
        return sdf.format(date);
    }

    /**
     * 格式当前日期
     * 
     * @param 日期格式
     * @return 格式化后的日期
     */
    public static String getNow(DateEnum fs) {
        return formatDate(now(), fs);
    }

    /**
     * 将字符串格式化为日期
     * 
     * @param date
     *            日期字符串
     * @param fs
     *            日期格式
     * @return 日期
     */
    public static Date parseDate(String date, DateEnum fs) {
        if (date == null || date.length() == 0) {
            return null;
        }
        // 日期格式
        SimpleDateFormat formatter = new SimpleDateFormat(fs.getValue());
        try {
            return formatter.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {
        if (date == null) {
            return "";
        }
        if (pattern == null) {
            pattern = "yyyy-MM-dd";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return (sdf.format(date));
    }

    /**
     * @param date
     * @return
     */
    public static String formatDateTime(Date date) {
        return (formatDate(date, "yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 以前yyyy-MM-dd HH:mm:ss刘柱更改yyyyMMddHHmmssSSS
     * 
     * @return
     */
    public static String formatDateTime() {
        return (formatDate(now(), "yyyyMMddHHmmssSSS"));
    }

    /**
     * @return
     */
    public static String formatDateTime2() {
        return (formatDate(now(), "yyyyMMddHHmmss"));
    }

    /**
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return (formatDate(date, "yyyy-MM-dd"));
    }

    /**
     * @param date
     * @return
     */
    public static String formatDate2(Date date) {
        return (formatDate(date, "yyyyMMdd"));
    }

    /**
     * @return
     */
    public static String formatDate() {
        return (formatDate(now(), "yyyy-MM-dd"));
    }

    /**
     * @return
     */
    public static String formatDate2() {
        return (formatDate(now(), "yyyyMMdd"));
    }

    /**
     * @param date
     * @return
     */
    public static String formatTime(Date date) {
        return (formatDate(date, "HH:mm:ss"));
    }

    /**
     * @return
     */
    public static String formatTime() {
        return (formatDate(now(), "HH:mm:ss"));
    }

    /**
     * @return
     */
    public static String formatTime2() {
        return (formatDate(now(), "HHmmss"));
    }

    /**
     * @return
     */
    public static Date now() {
        return (new Date());
    }

    /**
     * @param datetime
     * @return
     */
    public static Date parseDateTime(String datetime) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if ((datetime == null) || (datetime.equals(""))) {
            return null;
        } else {
            try {
                return formatter.parse(datetime);
            } catch (ParseException e) {
                return parseDate(datetime);
            }
        }
    }

    /**
     * @param date
     * @return
     */
    public static Date parseDate(String date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        if ((date == null) || (date.equals(""))) {
            return null;
        } else {
            try {
                return formatter.parse(date);
            } catch (ParseException e) {
                return null;
            }
        }
    }

    /**
     * @param date
     * @return
     */
    public static Date parseDate2(String date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        if ((date == null) || (date.equals(""))) {
            return null;
        } else {
            try {
                return formatter.parse(date);
            } catch (ParseException e) {
                return null;
            }
        }
    }

    /**
     * @param datetime
     * @return
     */
    public static Date parseDate(Date datetime) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        if (datetime == null) {
            return null;
        } else {
            try {
                return formatter.parse(formatter.format(datetime));
            } catch (ParseException e) {
                return null;
            }
        }
    }

    /**
     * @param o
     * @return
     */
    public static String formatDate(Object o) {
        if (o == null) {
            return "";
        }
        if (o.getClass() == String.class) {
            return formatDate(o);
        } else if (o.getClass() == Date.class) {
            return formatDate((Date) o);
        } else if (o.getClass() == Timestamp.class) {
            return formatDate(new Date(((Timestamp) o).getTime()));
        } else {
            return o.toString();
        }
    }

    /**
     * @param o
     * @return
     */
    public static String formatDateTime(Object o) {
        if (o.getClass() == String.class) {
            return formatDateTime(o);
        } else if (o.getClass() == Date.class) {
            return formatDateTime((Date) o);
        } else if (o.getClass() == Timestamp.class) {
            return formatDateTime(new Date(((Timestamp) o).getTime()));
        } else {
            return o.toString();
        }
    }

    /**
     * 给时间加上或减去指定毫秒，秒，分，时，天、月或年等，返回变动后的时间
     * 
     * @param date
     *            要加减前的时间，如果不传，则为当前日期
     * @param field
     *            时间域，有Calendar.MILLISECOND,Calendar.SECOND,Calendar.MINUTE,<br>
     *            * Calendar.HOUR,Calendar.DATE, Calendar.MONTH,Calendar.YEAR
     * @param amount
     *            按指定时间域加减的时间数量，正数为加，负数为减。
     * @return 变动后的时间
     */
    public static Date add(Date date, int field, int amount) {
        if (date == null) {
            date = new Date();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(field, amount);
        return cal.getTime();
    }

    /**
     * @param date
     * @param amount
     * @return
     */
    public static Date addMilliSecond(Date date, int amount) {
        return add(date, Calendar.MILLISECOND, amount);
    }

    /**
     * @param date
     * @param amount
     * @return
     */
    public static Date addSecond(Date date, int amount) {
        return add(date, Calendar.SECOND, amount);
    }

    /**
     * @param date
     * @param amount
     * @return
     */
    public static Date addMiunte(Date date, int amount) {
        return add(date, Calendar.MINUTE, amount);
    }

    /**
     * @param date
     * @param amount
     * @return
     */
    public static Date addHour(Date date, int amount) {
        return add(date, Calendar.HOUR, amount);
    }

    /**
     * @param date
     * @param amount
     * @return
     */
    public static Date addDay(Date date, int amount) {
        return add(date, Calendar.DATE, amount);
    }

    /**
     * @param date
     * @param amount
     * @return
     */
    public static Date addMonth(Date date, int amount) {
        return add(date, Calendar.MONTH, amount);
    }

    /**
     * @param date
     * @param amount
     * @return
     */
    public static Date addYear(Date date, int amount) {
        return add(date, Calendar.YEAR, amount);
    }

    /**
     * @return
     */
    public static Date getDate() {
        return parseDate(formatDate2());
    }

    /**
     * @return
     */
    public static Date getDateTime() {
        return parseDateTime(formatDateTime());
    }

    /**
     * 日期格式转换,从YYYYMMdd格式转换成YYYY-MM-dd
     * 
     * @param dateString
     * @return
     */
    public static String parseDateString(String dateString) {
        return formatDate(parseDate2(dateString));
    }

    /**
     * @param pattern
     * @param date
     * @return
     */
    public static String formatTimeStamp(String dat, String tim, int len) {
        SimpleDateFormat df = new SimpleDateFormat(dat);
        if (tim.length() > len) {
            return df.format(new Long(tim));
        }
        return tim;
    }

    /**
     * 输出：xxxx年xx月xx日 xx时:xx分:xx秒
     * 
     * @param dateTime
     * @return
     */
    public static String formateDate(String dateTime) {
        if (dateTime == null || "".equals(dateTime)) {
            return "";
        }
        return dateTime.substring(0, 4) + "年" + dateTime.substring(4, 6) + "月" + dateTime.substring(6, 8) + "日 " + dateTime.substring(8, 10) + ":"
                + dateTime.substring(10, 12) + ":" + dateTime.substring(12, 14);
    }

    public static String secToTime(int time) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (time <= 0) {
            return "00:00";
        } else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                timeStr = unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
                if (hour > 99) {
                    return "99:59:59";
                }
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    public static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10) {
            retStr = "0" + Integer.toString(i);
        } else {
            retStr = "" + i;
        }
        return retStr;
    }

    /**
     * <b>获取本月第一天：</b>
     * 
     * @param date
     *            日期
     * @param pattern
     *            日期模式
     * @return
     */
    public static String getFirstDayOfMonth(Date date, String pattern) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, 1);
        DateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(calendar.getTime());
    }

    /**
     * <b>获取本月最后一天：formatted as yyyy-MM-dd</b>
     * 
     * @return
     */
    public static String getLastDayOfMonth() {
        Calendar calendar = Calendar.getInstance();
        DateFormat dateFormat = new SimpleDateFormat(PATTERN_DATE);
        calendar.set(Calendar.DATE, 1);
        calendar.roll(Calendar.DATE, -1);
        return dateFormat.format(calendar.getTime());
    }
}
